namespace ghost 
{
	/**角色基类，编写所有角色类均有的基础数据和基础方法*/
	export class Role implements IUpdate,IPoolObject,map2D.IRole
	{		
		public constructor(sceneMgr:SceneManager=null)
		{
			let s = this;
			s._scene = sceneMgr?sceneMgr:SceneManager.instance;			
			s._layerMgr = s._scene.module.layerMgr;
			s._isReset = true;
			s._skin = new RoleSkin(s);
			s._speed = 8;
			s._direction = 0;			
			// s._hitGrids = [];
			s._directSts = -1;
			s._operSts = -1;
			s._sts = -1;
			s._staticRole = false;
			s._moveState = new MoveState(this);
			let g:Laya.Graphics;
			if(GameManager.debug)
			{
				g = s._skin.graphics;
				// g.beginFill(0xff0000,1);
				g.drawCircle(0,0,10,"#ff0000");
				// g.endFill();
			}			
		}		
		/**创建到舞台*/
		public create(createSts:number=StsType.STAND,createDir:number=0,x:number=0,y:number=0):void
		{let s = this;
			if(!s._isCreated)
			{					
				s._isCreated = true;
				s._isDead = false;
				s._createSts = createSts;
				s._createDir = createDir;
				s._absX = x;
				s._absY = y;			
				s._absZ = 0;
				// s._scene.module.roleLay.addChild(s._skin);
				let skinObj = s._cfg && s._cfg.skin?s._cfg.skin:{
					skinType:SkinType.SEQ,
                    clothes:s._cfg.roleID,
                    action:s._cfg.roleID
				};
				s.setLayerType(s._cfg.layerType);
				s.setSkin(skinObj);				
				s._bornTime = s._scene.timeTick;
				s.worldPosSet();				
			}
		}
		/**设置角色的层级类型
		 * @param layerType 层级类型 参考LayerType常量
		 * @param pr 自定义父级使用
		 * @param childIndex 所处下标
		*/
		public setLayerType(layerType:number,pr:GYSprite=null,childIndex:number=NaN):void
		{
			let s = this;
			s._layerType = layerType?layerType:map2D.LayerType.ROLE;
			if(pr)
			{
				s._layer = pr;
				s._layerType = map2D.LayerType.DEF;
				if(<Role>s._owner != s && s._owner && s._owner._layer == s._layer)
				{
					s._layer.addChildAt(s._skin, childIndex >= 0?childIndex : s._layer.getChildIndex(s._owner._skin));//优先外部传进来的下标
				}
				else
					s._layer.addChild(s._skin);
				return;
			}	
			// if(layerType == map2D.LayerType.ROLE_BACK)
			// {				
			// 	s._layerType = layerType;
			// 	s._layer = s._owner._skin;
			// 	s._layer.addChildAt(s._skin, childIndex);
			// }				
			// else if(layerType == map2D.LayerType.ROLE_FRONT)
			// {				
			// 	s._layerType = layerType;				
			// 	s._layer = s._owner._skin;
			// 	s._layer.addChild(s._skin);
			// }
			// else		
			// {
				s._layer = s._layerMgr.getLayer(layerType);
				if(s._layer == null)
				{
					s._layerType = map2D.LayerType.ROLE;
					s._layer = s._scene.module.roleLay;
				}			
					
				s._layer.addChild(s._skin);
			// }
			
		}
		/**计算角色朝向目标的旋转的弧度*/
		public calAutoAngle(ox:number,oy:number,x:number,y:number):number
		{
			let s= this;
			let disX:number,disY:number,aDisX:number,aDisY:number;
			let agl:number;			
			disX = x - ox;
			disY = y - oy;
			aDisX = disX<0?-disX:disX;
			aDisY = disY<0?-disY:disY;
			if(disX!=disX || disY!=disY || aDisX < 1 && aDisY < 1)			
				agl = s._skin.rotation * MathConst.ROTATION_ANGLE;
			else
				agl = (disX < 0.0000001&& disX > -0.0000001)?(disY < 0?-MathConst.HALF_PI:MathConst.HALF_PI):Math.atan2(disY,disX);						
			return agl;
		}
		/**计算角色朝向目标的旋转的角度*/
		public calAutoRotation(ox:number,oy:number,x:number,y:number):number
		{
			let s= this;
			let deg:number;
			let isReserve:boolean;
			deg = s.calAutoAngle(ox,oy,x,y);
			deg *= MathConst.ANGLE_ROTATION;
			if(s._autoRotation == deg)
				return s._autoRotation;
			isReserve = s._dirScaleX < 0;
			s._autoRotationNotInvert = deg;
			s._autoRotation = s._autoRotationNotInvert + (isReserve?0:-180);
			return s._autoRotation;
		}
		protected worldPosSet():void
		{
			let s= this;
			s._skin.x = s._absX - s._scene.mapX;
			s._skin.y = s._absY - s._scene.mapY;			
		}
		public enterLoop(t:number,index:number):void
		{
		}
		public exitLoop(t:number,index:number):void
		{	
		}
		public update(t:number, index:number):boolean
		{
			let s = this;			
			s._seq = index;
			if(s._paused)return false;			
			// s._skin.visible = s.visible = s.isInVisRect();			
			// if(s._visible)
			// {
			// 	let state:number;
			// 	state = s._scene.barrier.barrierState(s._absX,s._absY,map2D.Barrier.SHADOW);
			// 	s.alpha = ((state & map2D.Barrier.SHADOW) > 0)?0.5:1;
			// }
			s.enterLoop(t,index);
			s.moveSmart();
			s.posCheck();
			return true;
		}
		protected posCheck():void
		{
			let s= this;
			if(s._oldAbsX != s._absX || s._oldAbsY != s._absY)
			{
				s._posChanged = true;
				s.posChange();
				s._oldAbsX = s._absX;
				s._oldAbsY = s._absY;
			}
		}
		/**坐标改变（当前坐标与上一帧坐标不一样时调度）*/
		protected posChange():void
		{
			let s = this;
			if(s._visible)			
			s.barrierStateCheck();
		}
		protected barrierStateCheck():void
		{
			let s = this;
			let state:number;
			if(s.col == s.col)
			{
				state = s._scene.barrier.barrierGridState(s.col,s.row,map2D.Barrier.SHADOW);
				s.setAlphaTop((state > 0?0.5:1)*s.skinAlpha);
			}
		}
		public setAlphaTop(val:number)
		{
			let s= this;
			if(s._skin == null)return;
			s._skin.alpha = val;
			s.depthValue = val==1?0:1;
		}
		public updateLater(t:number, index:number):boolean
		{
			let s = this;
			if(s._layerType != map2D.LayerType.DEF)//自定义层级的不进行视图判断
			{
				if(s._posChanged || s._scene.mapPosChanged)
				{
					s._isInVisRect = s.isInVisRect();
					s.setVisible(s._isInVisRect && s._displayVisible);
				}				
			}
			s.exitLoop(t,index);
			return true;
		}
		public setYIndex(ind:number):void
		{
			let s = this;
			if(s._skin && s._skin.parent)
				(<GYSprite>s._skin.parent).setChildIndex(s._skin,ind);
		}
		public setDirection(sts:number):void
		{
			let s = this;			
			s._dirMove = true;
			s._targetMove = false;
			s._directSts = sts;
			if(sts == -1)
			{				
				s.setOperSts(StsType.STAND);				
			}	
		}
		public setOwner(val: AniRole): void {
			let s = this;
			s._owner = val;			
		}
		public get directSts():number
		{
			return this._directSts;
		}
		public get sts():number
		{
			return this._sts;
		}
		
		public getAutoAngle(ox:number,oy:number,x:number,y:number):number
		{
			let s= this;
			let disX:number,disY:number,aDisX:number,aDisY:number;
			let agl:number;			
			disX = x - ox;
			disY = y - oy;
			aDisX = disX<0?-disX:disX;
			aDisY = disY<0?-disY:disY;
			if(disX!=disX || disY!=disY || aDisX < 1 && aDisY < 1)
				agl = s._skin.rotation * MathConst.ROTATION_ANGLE;
			else
				agl = disX == 0?(disY < 0?-MathConst.HALF_PI:MathConst.HALF_PI):Math.atan2(disY,disX);			
			return agl;
		}
		public getAutoRotation(ox:number,oy:number,x:number,y:number):number
		{
			let s= this;
			return s.getAutoAngle(ox,oy,x,y)*MathConst.ANGLE_ROTATION;
		}
		public setOperSts(sts:number,toDirection:number=0):void
		{
			let s = this;			
			if(StsType.cannotAction(s._sts) || s._sts == StsType.FALL)
				return;
			s._operSts = sts;
			s._directSts = -1;
			if(toDirection > -1)
				s._direction = toDirection;
			s._movePath = null;
		}
		public setSceneParam(cfg:any)
		{
			let s= this;
			if(cfg)
			{
				for(var key in cfg)
				{
					if(key == "roleID")
					continue;
					if(key in s)
					{
						s[key] = cfg[key];
					}
				}						
			}
			
		}
		public setSkin(skinObj:any):void
		{
			
		}
		public reset(cfg:any, r:number = 0):void{}
		/**设置角色动画状态
		 * @param sts 状态参考 StsType，默认0
		 * @param direction 方向，参考DirectionType 默认-1
		*/
		public setSts(sts:number=0,direction:number=-1):void{
						
		}
		
		public parseConfig(roleType:number, cfg:any):void{
			let s = this;
			s._cfg = cfg;	
			s._roleType = roleType;
			s._roleListType = cfg.roleListType;
			s._roleID = cfg.roleID;
			s._oldAbsX = s._oldAbsY = NaN;
			if(s._cfg.absX)s._absX = s._cfg.absX;
			if(s._cfg.absY)s._absY = s._cfg.absY;
			s._staticRole = !!cfg.staticRole;
		}
		/**判断坐标处是否通行
		 * @param x 世界坐标x
		 * @param y 世界坐标y
		 * @return 返回大于0为通行
		*/
		public canPass(x:number,y:number,flag:number=map2D.Barrier.LAND,h_gs:number=0):number
		{
			let s = this;
			let state:number,j:number,len2:number;
			let arr2:number[];
			if(s._scene.ignoreBarrier)
				return map2D.Barrier.PASS;
			
			if(s.inBarrierPos)//如果已经在障碍上，只判断当前坐标即可，因为允许从当前障碍格子走出去，不需要判断太多顶点
				return s._scene.barrier.barrierState(x,y,flag);	
			arr2 = Role.posArr;
			arr2.length = 0;
			if(h_gs == 0)
			{
				state = s._scene.barrier.barrierState(x,y,flag);				
				if(state <= 0)
					return state;
			}
			else
			{
				arr2.push(x - h_gs, y - h_gs, x + h_gs, y - h_gs, x + h_gs, y + (h_gs >> 1), x - h_gs, y + (h_gs >> 1));						
				len2 = arr2.length;
				for(j = 0;j < len2;j += 2)
				{
					state = s._scene.barrier.barrierState(arr2[j],arr2[j + 1],flag);				
					if(state <= 0)
						return state;
				}			
			}
			
			return state;
		}
		/**寻路到指定坐标
		 * @param toX 世界坐标x
		 * @param toY 世界坐标y		 
		 * @param speed 移动速度，默认NaN，使用角色本身默认速度speed
		 * @param callBack 结束会回调 (code:number)=>void code 0表示寻路成功 1表示寻路失败，目标点不可达
		 * @param thisObj
		 * @param sceneCall 寻路结束是否通知场景逻辑 默认true
		 * @param sts 寻路过程使用的动作状态
		 * @param nMaxTry 最大寻路步数限制
		 * @param endFlag 结束标志，默认-1，不检测结束格子标志
		*/
		public findPathTo(toX:number,toY:number,speed:number=NaN,callBack:(code:number,msg:string)=>void=null,thisObj:any=null,sceneCall:boolean=true,sts:number=NaN,nMaxTry:number=0,endFlag:number=-1,route:number[]=null):number[][]
		{
			let s = this;
			if(s._scene.isBarrier(toX, toY, map2D.Barrier.LAND | map2D.Barrier.AIR)){
				console.error("目标点是障碍点：x:"+ toX + ",y:"+ toY);
			}
			let gridSize:number;										
			// let t:number;
			let movePath:number[][];
			if(s._directSts > -1)return;
			s.destroyFindThread();
			gridSize = s._scene.gridSize;	
			s._moveType = MoveType.FIND;			
			// t = Date.now();		
			if(Math.abs(s._absX - toX) < gridSize && Math.abs(s._absY - toY) < gridSize)//一个不够的距离直接走
			{
				movePath = [[]];
				movePath[0][0] = toX / gridSize |0;
				movePath[0][1] = toY / gridSize |0;
				movePath[0][3] = toX;
				movePath[0][4] = toY;
				movePath[0][2] = 1;
				s.startPathMove(movePath,speed,callBack,thisObj,sceneCall, sts);	
			}
			else
			{
				// movePath = s._scene.aStar.doSearch(s._absX / gridSize |0, s._absY / gridSize |0, toX / gridSize |0,toY / gridSize |0, null, nMaxTry, endFlag);
				s._findPathThread = s._scene.aStar.runDoSearchThread((thread:Thread)=>{
					let movePath:number[][];
					if(s._moveType != MoveType.FIND)return;
					movePath = thread.returnValue;
					let i:number,len:number,endX:number,endY:number;
					if(movePath && movePath.length > 0)
					{
						len = movePath.length;				
						endX = movePath[0][0] * gridSize | 0;
						endY = movePath[0][1] * gridSize | 0;
						movePath[0][2] = 1;
						if(Math.abs(endX - toX) < gridSize && Math.abs(endY - toY) < gridSize)
						{
							movePath[0][3]=toX;
							movePath[0][4]=toY;
						}
						else
						{
							movePath[0][3]=endX;
							movePath[0][4]=endY;
						}
						
						for(i=1;i<len;++i)
						{
							if(i == len - 1)
							{							
								break;
							}
							//斜着走的情况，最后一格子不走准确坐标
							if(movePath[i - 1][0] - movePath[i][0] == movePath[i][0] - movePath[i + 1][0] && movePath[i - 1][1] - movePath[i][1] == movePath[i][1] - movePath[i + 1][1])
							{
								movePath[i][2] = -1;
							}
						}
						s.startPathMove(movePath,speed,callBack,thisObj,sceneCall, sts);
					}
					else
					{
						// if(sceneCall)
						// 	s._scene.sceneLogic.playerPathMoveEnd(s);				
						if(callBack!=null)				
						{
							if(callBack.length == 0)
								callBack.call(thisObj);
							else
								callBack.call(thisObj, 1, "{mapName:" + s._scene.mapName + ",from:[" + s._absX + "," + s._absY + "],to:[" + toX + "," + toY + "],gridSize:" + gridSize + "}");
						}
					}
				},s._absX / gridSize |0, s._absY / gridSize |0, toX / gridSize |0,toY / gridSize |0, null, nMaxTry, endFlag, map2D.Barrier.LAND, -1, route);
				
			}
			return movePath;
		}
		public stopMoveSmart():void
		{
			let s = this;
			if(s._hasTargetPos)
			{
				s._hasTargetPos = false;
				s.moveFlagSet(false);	
			}			
		}
		protected moveFlagSet(val:boolean):void
		{
			let s = this;
			s._targetMove = val;
			s._moveType = MoveType.NONE;			
			if(!val)
				s._moveEndObj = s._moveEndCall = null;				
		}
		public stopFindPath():void
		{
			let s = this;
			if(s._movePath && s._movePath.length > 0)
			{
				s.stopMoveSmart();
				s._movePath = null;
				s._moveType = MoveType.NONE;
			}
			s.destroyFindThread();
		}
		public destroyFindThread():void
		{
			let s= this;
			if(s._findPathThread)
			{
				s._findPathThread.destroy();
				s._findPathThread = null;
			}
		}
		/**执行根据寻路路径移动*/
		public startPathMove(movePath:number[][],speed:number=NaN,callBack:(code:number,msg:string)=>void=null,thisObj:any=null,sceneCall:boolean=false,sts:number=NaN):void
		{
			let s = this;			
			s.findPathSpeed = speed;
			s._moveType = MoveType.FIND;
			s.findPathSts = sts;
			s._movePath = movePath;
			s._pathMoveEndCall = callBack;
			s._pathMoveEndObj = thisObj;
			s._pathSceneCall = sceneCall;
			s.pathMove();
		}
		private pathMove():void
		{
			let s = this;
			let arr:number[];
			let flag:number;
			let time:number;
			let moveSts:number,tX:number,tY:number;		
			if(s._isDead)
				return;
			if(s._movePath && s._movePath.length > 0)
			{
				let gridSize:number = s._scene.gridSize;
				let len:number;
				moveSts = s.findPathSts==s.findPathSts?s.findPathSts:StsType.RUN;
				len = s._movePath.length;				
				while(--len>-1)
				{
					flag = s._movePath[len][2];
					if(flag == -1)continue;
					arr = s._movePath[len];
					s._movePath.length = len;
					if(flag == 1 && s.canPass(arr[3],arr[4]) > 0)//准确定位的时候不在格子中心，需要再一次判断是否踩在障碍上
					{
						tX = arr[3];
						tY = arr[4];
					}	
					else
					{
						tX = (arr[0] + 0.5)* gridSize;
						tY = (arr[1] + 0.5)* gridSize;
					}
					time = PositionUtil.calculateDistance(s._absX,s._absY,tX,tY) / (s._findpathSpeedPerMS*s._pathMoveRate);
					s.moveTo(tX,tY,s.pathMove,s,moveSts,time,-1,NaN);
					break;
				}				
			}
			else
			{
				let func:Function;
				let obj:any;
				func = s._pathMoveEndCall;
				obj = s._pathMoveEndObj;
				s._pathMoveEndCall = s._pathMoveEndObj = null;	
				s._moveType = MoveType.NONE;	
				// if(s._pathSceneCall)		
				// {
				// 	s._scene.sceneLogic.playerPathMoveEnd(s);
				// 	s._pathSceneCall = false;
				// }
				
				if(!s._targetMove)//判断一下是否又开始新的行走目标，否则自动恢复成站立
					s.setSts(s.findPathSts == s.findPathSts?s.findPathSts:StsType.STAND);
					
				if(func!=null)				
				{
					if(func.length == 0)
						func.call(obj);
					else
						func.call(obj, 0);						
				}
			}				
		}
		/**计算向角度方向agl移动步长speed(此方法会判断下个坐标是否障碍)
		 * @param agl 角度
		 * @param speed 步长 默认NaN 使用角色本身的移动速度
		 * @return MoveState 返回计算结果
		*/
		protected moveStep(agl:number, speed:number = NaN, ignoreMoveStopRole:Role=null):MoveState
		{			
			let s = this;
			let barrierStateX:number,barrierStateY:number;			
			let gridSize:number;
			gridSize = s._scene.sceneLogic._posGridW;
			if(speed != speed)
				speed = s._speed;
			s._moveState.setData(s,agl,speed,gridSize, gridSize);
			if(s._scene.ignoreBarrier)
			{
				s._moveState.result = MoveResult.PASS;
				return s._moveState;
			}
			
			if(s._moveState.isXChange())
			{
				barrierStateX = s.canPass(s._moveState._toX,s._absY,map2D.Barrier.STEP_PASS);			
				if(barrierStateX == 0)			
					s._moveState.barrierX();
				else
					s._moveState.result |= MoveResult.PASS;
			}
			if(s._moveState.isYChange())
			{
				barrierStateY = s.canPass(s._absX,s._moveState._toY,map2D.Barrier.STEP_PASS);
				if(barrierStateY == 0)			
					s._moveState.barrierY();
				else
					s._moveState.result |= MoveResult.PASS;
			}
			if(s._moveState.result == MoveResult.NONE)		
				s._moveState.result = MoveResult.BARRIER;
			return s._moveState;
				
		}
		/**往指定方向行走一步长*/
		public moveDir(agl:number, speed:number=NaN,ignoreMoveStopRole:Role=null):MoveState
		{			
			let s = this;			
			let moveState:MoveState;
			if(s._isDead)return null;
			// s._moveType = MoveType.DIR;
			moveState = s.moveStep(agl, speed==speed?speed:s._speed,ignoreMoveStopRole);
			if((moveState.result & MoveResult.HIT) == 0)
			{				
				s._absX = moveState._toX;
				s._absY = moveState._toY;				
				s.setSts(StsType.STAND, map2D.DirectionType.getDirectorSts(agl));	
			}			
			return moveState;
		}
		/**移动到往指定坐标处(直线移动，忽略障碍)
		 * @param abX 目标世界坐标X
		 * @param abY 目标世界坐标X
		 * @param callBack 移动结束回调，默认null
		 * @param thisObj 回调的this，默认null
		 * @param sts 移动使用的动作状态，默认StsType.Run，-1则不改变当前状态
		 * @param time 移动用时，默认500毫秒
		 * @param rotateMove 是否旋转移动 默认false
		 * @param dir 指定移动方向 默认-1 则跟进前进方向计算
		 * @param endSts 行走结束时切换的状态 默认-1表示恢复成站立状态，结束不做状态处理则设为NaN
		*/
		public moveTo(abX:number,abY:number,callBack:any=null,thisObj:any=null,sts:number=NaN,time:number=500,dir:number=-1,endSts:number=-1):void
		{
			let s = this;			
			let agl:number,disX:number,disY:number;		
			sts = sts == sts?sts:StsType.STAND;
			s._dirMove = false;			
			s._moveType = s._movePath?MoveType.FIND:MoveType.MOVE;
			s.moveFlagSet(true);			
			disX = abX - s._absX;
			disY = abY - s._absY;			
			if(sts > -1)
			{
				if(dir == -1)
				{
					agl = Math.atan2(disY,disX);
					dir = map2D.DirectionType.getDirectorSts(agl)
				}
				s.setSts(sts, dir);
			}
			let per:number = CommonUtil.frameRate / 60;
			s._speedX = Math.cos(agl) * s._speed * per;
			s._speedY = Math.sin(agl) * s._speed * per;
			s._targetX = abX;
			s._targetY = abY;
			if(s._autoRotate)
			{				
				s.setRotation(s.calAutoRotation(s._absX,s._absY,s._targetX,s._targetY));				
			}

			s._hasTargetPos  = s._targetX == s._targetX || s._targetY== s._targetY;
			s._moveEndCall = callBack;
			s._moveEndObj = thisObj;
			s._moveEndSts = endSts == -1?StsType.STAND:endSts;
		}
		protected moveSmart():void
		{
			let s = this;
			if(s._sts > StsType.RUN)
				return;
			if(!s._targetMove)
				return;
			if(s._targetX == s._targetX)
			{				
				s._absX += s._speedX;
				if(Math.abs(s._targetX - s._absX) <= Math.abs(s._speedX))
				{
					s._absX = s._targetX;
					s._targetX = NaN;
				}
			}
			if(s._targetY == s._targetY)
			{
				s._absY += s._speedY
				if(Math.abs(s._targetY - s._absY) <= Math.abs(s._speedY))
				{
					s._absY = s._targetY;
					s._targetY = NaN;
				}
			}
			s._hasTargetPos  = s._targetX == s._targetX || s._targetY== s._targetY;
			s.moveSmartEnd();
			if (s._targetMove)
				s.inArea();
		}
		/**移动结束函数*/
		protected moveSmartEnd():void
		{
			let s= this;	
			if(!s._hasTargetPos)
			{	
				let func:Function,obj:any;
				func = s._moveEndCall;
				obj = s._moveEndObj;					
				s.moveFlagSet(false);
				s.setSts(StsType.STAND, s._direction);
				if(func!=null)					
					func.call(obj);
					
			}
		}
		/**标识进入某区域，当坐标变更请调此方法刷新，以保证角色标记的区域正确*/
		public inArea(): void {
			
		}
		public outArea(): void {
			
		}
		public get direction():number
		{
			return this._direction;
		}
		public set findPathSpeed(val:number)
		{
			let s= this;
			if(s._findPathSpeed == val)return;
			if(val == val)
			{
				s._findPathSpeed = val;
				s._findpathSpeedPerMS = val * CommonUtil.frameRate / 1000;
			}
			else
			{
				s._findPathSpeed = s._speed
				s._findpathSpeedPerMS = s._speedPerMS;
			}			
		}
		/**寻路移速，调用findPathTo指定，如不指定，则使用默认速度speed*/
		public get findPathSpeed():number
		{
			return this._findPathSpeed;
		}
		public set speed(val:number)
		{
			let s= this;
			s._speed = val;
			s._speedPerMS = val * 60 / 1000;
		}
		public get speed():number
		{
			return this._speed;
		}
		public get absX():number
		{
			return this._absX;
		}
		public get absY():number
		{
			return this._absY;	
		}
		public get absZ():number
		{
			return this._absZ;	
		}
		public set absX(val:number)
		{
			let s = this;				
			s._absX = val;
		}
		public set absY(val:number)
		{
			let s = this;
			s._absY = val;
		}
		public set absZ(val:number)
		{
			let s = this;
			s._absZ = val;
		}		

		public get cfg():any
		{
			return this._cfg;
		}

		public get areaRowMin():number
		{
			let s = this;
			return s._staticRole?s._areaRowMin:Math.floor((s._absY + s._areaTop) / s._scene.mapAreaSize);
		}

		public get areaColMin():number
		{
			let s = this;
			return s._staticRole?s._areaColMin:Math.floor((s._absX + s._areaLeft) / s._scene.mapAreaSize);
		}

		public get areaRowMax():number
		{
			let s = this;
			return s._staticRole?s._areaRowMax:Math.floor((s._absY + s._areaBottom) / s._scene.mapAreaSize);
		}

		public get areaColMax():number
		{
			let s = this;
			return s._staticRole?s._areaColMax:Math.floor((s._absX + s._areaRight) / s._scene.mapAreaSize);
		}
		
		/**是否在视图内(以自身的模型大小是否在摄像机内判断)*/
		// public isInVisRect():boolean
		// {
		// 	let s = this;			
		// 	let abX:number,abY:number;						
		// 	if(s._layerType >= map2D.LayerType.ROLE_BACK)
		// 	{
		// 		abX = s._owner._absX;
		// 		abY = s._owner._absY;
		// 	}	
		// 	else
		// 	{
		// 		abX = s._absX;
		// 		abY = s._absY;
		// 	}
		// 	if(s._skinPart)
		// 	{
		// 		return abX + s._skinPart._areaRight > s._scene.mapX && abX + s._skinPart._areaLeft < s._scene.mapRight && abY + s._skinPart._areaBottom > s._scene.mapY && abY + s._skinPart._areaTop < s._scene.mapBottom;
		// 	}
		// 	return abX > s._scene.mapX && abX < s._scene.mapRight && abY > s._scene.mapY && abY < s._scene.mapBottom;			
		// }
		/**是否在视图内*/
		public isInVisRect():boolean
		{
			let s = this;			
			let abX:number,abY:number;						
			if(s._layerType >= map2D.LayerType.ROLE_BACK)
			{
				abX = s._owner._absX;
				abY = s._owner._absY;
			}	
			else
			{
				abX = s._absX;
				abY = s._absY;
			}
			return !(abX + s._areaRight < s._scene.mapX || abX + s._areaLeft > s._scene.mapRight || abY + s._areaBottom < s._scene.mapY || abY + s._areaTop > s._scene.mapBottom);
		}

		public get inPool():boolean
		{
			return this._inPool;
		}

		public set inPool(value:boolean)
		{
			this._inPool = value;
		}

		
		public isDel():boolean
		{
			return this._isDel <= this._scene.timeTick;
		}

		
		/**标记移除，角色将在下帧移除*/
		public del():boolean
		{
			let s= this;					
			if(s.isDel())				
				return false;			
			s._isDel = s._scene.timeTick;						
			return true;					
		}
		/**角色id，关联角色的技能、皮肤等*/
		public get roleID():string
		{
			return this._roleID;
		}
		/**角色人物唯一标识*/
		public get id():number
		{
			return this._id;
		}
		public get layerType():number
		{
			return this._layerType;
		}
		public set layerType(val:number)
		{
			this.setLayerType(val);
		}
		public get layer():GYSprite
		{
			return this._layer;
		}
		public get roleType():number
		{
			return this._roleType;
		}
		public get roleListType():number
		{
			return this._roleListType;
		}
		/**层级索引*/
		public get seq():number
		{
			return this._seq;
		}

		public set anchorX(val:number)
		{
			let s =this;
			if(s._skinPart)
				s._skinPart.x = -val;
		}
		public set anchorY(val:number)
		{
			let s =this;
			if(s._skinPart)
				s._skinPart.y = -val;
		}

		public get anchorX():number
		{
			let s =this;
			return s._skinPart?-s._skinPart.x:0;
		}
		public get anchorY():number
		{
			let s =this;
			return s._skinPart?-s._skinPart.y:0;
		}
		public set alpha(val:number)
		{
			if(this.skin == null)return;
			this.skin.alpha = val;
		}
		public get alpha():number
		{
			return this.skin?this.skin.alpha:1;
		}
		public set scaleX(val:number)
		{
			if(this.skin == null)return;
			this.skin.scaleX = val;
		}
		public get scaleX():number
		{
			return this.skin?this.skin.scaleX:1;
		}
		public set scaleY(val:number)
		{
			if(this.skin == null)return;
			this.skin.scaleY = val;
		}
		public get scaleY():number
		{
			return this.skin?this.skin.scaleY:1;
		}
		public setRotation(val:number)
		{
			if(this._skin == null)return;
			this._skin.rotation = val;
		}
		public getRotation():number
		{
			return this._skin?this._skin.rotation:0;
		}
		/**角色是否可视*/
		public isVisible():boolean
		{
			let s= this;
			let padding:number = 50;
			return !(s._absX < s._scene.mapMinX - padding || s._absX > s._scene.mapMaxX + padding || s._absY < s._scene.mapMinY - padding || s._absY > s._scene.mapMaxY + padding);
		}
		/**当前角色可视状态*/
		public getVisible():boolean
		{
			return this._visible;
		}		
		/**设置角色可视状态(设置是否显示，请使用setDisplayVisble，因为角色离开视口区域会自动被设置setVisible为false)
		 * 角色可视状态由_visible和_displayVisible共同决定
		 * */
		public setVisible(value:boolean)
		{
			let s= this;
			if(s._visible == value)
				return;
			s._visible = value;
			s._skin.visible = value;
		}
		/**获取当前显示对象的显示状态**/
		public getDisplayVisible():boolean
		{
			return this._displayVisible;
		}
		/**设置当前显示对象的显示状态**/
		public setDisplayVisible(val:boolean)
		{
			let s = this;
			if(s._displayVisible == val)return;
			s._displayVisible = val;
			s.setVisible(s._isInVisRect && s._displayVisible);
		}

		public get staticRole():Boolean
		{
			return this._staticRole;
		}
		public get userName():string
		{
			return this._userName;
		}
		public get bornTime():number
		{
			return this._bornTime;
		}
		public set bornTime(val:number)
		{
			this._bornTime = val;
		}
		
		public get skin():RoleSkin
		{
			return this._skin;
		}
		public get skinObj():any
		{
			return this._skinObj;
		}
		public get skinPart():ISkinPart
		{
			return this._skinPart;
		}		
		public setIdFromServer(id:number):void
		{
			this._id = id;
		}
		public updateRateLoopFlag():void{}
		/**切换角色智能
		 * @param type AIEnum 由开发者自己定义常量id
		*/
		public changeSmart(type:AIEnum):void{}	
		public updateView():void
		{
			
		}
		/**场景层级，除去自定义层级，角色身上的层级，其他属于场景层级*/
		public isSceneLayer():boolean
		{
			return this._layerType < map2D.LayerType.ROLE_BACK;
		}
		public pause(includeMyObj:boolean = false):void{}
		public resume(includeMyObj:boolean = false):void{}
		protected toPool():void
		{
			let s = this;
			PoolUtil.toPool(s, s.constructor);
		}
		public beforeToPool():void
		{
			let s = this;	
			s._paused = false;			
			s._isReset = true;						
			s._direction = 0;			
			if(s._isDel == Number.MAX_VALUE)
				s._isDel = s._scene.timeTick;
			s.destroyFindThread();
			s.moveFlagSet(false);
			s._hasTargetPos = false;	
			s._moveType = MoveType.NONE;

			s._absX = s._absY = NaN;
			s._directSts = -1;
			s._operSts = -1;
			s._sts = -1;
			if(s._skinPart)
			{				
				s._skinPart.dispose();
				s._skinPart = null;
			}
			s._skin.clear();
			s._id = NaN;	
			s._ownerData = null;				
				
			if(s._skin.getStyle())
				s._skin.rotation = 0;
			
			s._absZ = 0;			
					
		}
		
		/**清理角色*/
		public clear():void{
			let s = this;			
			if(s._inPool)return;	
			s.beforeToPool();			
			s.toPool();			
		}		
        public outPoolInit(): void
		{	
			let s = this;
			let def:map2D.Default;
			def = s._scene.getDefault();
			s.skinAlpha = 1;	
			s.skin.visible = true;		
			s._posChanged = true;		
			s._speed = def.move_speed / Main.frameRate | 0;
			s._speedPerMS = s._speed * Main.frameRate / 1000;
			s._targetY = s._targetX = s._speedX = s._speedY = NaN;			
			s._hasTargetPos = false;
			s._roleID = "1";
			s._roleListType = -1;
			s._pathMoveRate = 1;
			s._isCreated = false;			
			s._isDel = Number.MAX_VALUE;
			s._id=++Role.idCount;
			s.col = s.row = NaN;			
			s.areaCol = s.areaRow = NaN;
			s.areaKey = null;
			s._headJumpH = s._floatH = 0;
			s._settingHeadH = NaN;
			s._visible = s._displayVisible = s._isInVisRect = true;	
			s._headH = 0;			
			s._settingHeadH = NaN;			
		}
        public dispose(): void
		{
			let s =this;
			s.clear();
		}

		private static _lastT:number;
		public static getRoleId():string
		{
			let t:number = Date.now();
			if(Role._lastT == t)
				++t;
			Role._lastT = t;
			return t + "";
		}
		public static getDefaultConfig(skinType:number = NaN):any
		{
			return {
				absX:0,
				absY:0,
				areaRect:[-300,-150,300,300],				
				roleType:RoleType.PLAYER,
				roleID:Role.getRoleId()
			};
		}

		protected _paused:boolean;
		public _id:number;
		protected _roleID:string;
		protected _isCreated:boolean;
		protected _isReset:boolean;
		protected _areaRowMin:number;
		protected _areaColMin:number;
		protected _areaRowMax:number;
		protected _areaColMax:number;
		protected _areaLeft:number;
		protected _areaRight:number;
		protected _areaTop:number;
		protected _areaBottom:number;		
		protected _roleType:number;		
		protected _roleListType:number;
		protected _cfg:any;
		protected _inPool:boolean;
		protected _absX:number;
		protected _absY:number;
		protected _absZ:number;
		protected _bornX:number;
		protected _bornY:number;
		protected _oldAbsX:number;
		protected _oldAbsY:number;
		protected _sts:number;				
		public _isDel:number;
		protected _staticRole:boolean;
		public _scene:SceneManager;
		public _layerMgr:LayerManager;
		public _visible:boolean;
		public _displayVisible:boolean;
		protected _isInVisRect:boolean;
		// protected _gameCfg:any;	
		protected _skin:RoleSkin;	
		protected _skinPart:ISkinPart;
		protected _speed:number;
		protected _speedX:number;
		protected _speedY:number;
		protected _speedH:number;
		protected _targetX:number;
		protected _targetY:number;
		protected _targetH:number;
		public _autoRotation:number;
		public _autoRotationNotInvert:number;
		protected _autoRotate:boolean;
		// protected _autoScale:number;
		protected _hasTargetPos:boolean;
		protected _moveEndCall:Function;
		protected _moveEndObj:any;
		protected _speedPerMS:number;
		protected _direction:number;
		protected _dirMove:boolean;
		public _targetMove:boolean;
		// protected _curMoveTween:GYLite.GYTween;		    					
		protected _skinType:number;
		protected _skinObj:any;
		protected _seq:number;
		// protected _hitGrids:number[];
		protected _operSts:number;
		protected _directSts:number;
		protected _movePath:number[][];
		protected _userName:string;		
		protected _bornTime:number;
		public updating:boolean;
		public static posArr:number[]=[];
		public col:number;
		public row:number;
		public areaCol:number;
		public areaRow:number;
		public areaKey:string;
		public inBarrierPos:boolean;
		public inAirPos:boolean;
		public _dirScaleX:number;	
		public _dirScaleY:number;	
		/**当前翻转的方向，DirectionType常量*/
		public _scaleDir:number;	
		protected _moveState:MoveState;
		public _isDead:boolean;

		protected _pathMoveEndCall:(code:number,msg:string)=>void;
		protected _moveEndSts:number;
		protected _pathMoveEndObj:any;
		protected _pathMoveRate:number;
		protected _moveType:number;

		protected _findPathSpeed:number;
		protected _findpathSpeedPerMS:number;
		/**寻路时使用的动作状态*/public findPathSts:number;
		/**寻路结束是否通知逻辑场景*/
		protected _pathSceneCall:boolean;
		protected _findPathThread:Thread;
		public _floatH:number;
		public _headH:number;
		public _headJumpH:number;
		public moveTimeTicker:map2D.TimeTicker;
		public _createSts:number;
		public _createDir:number;
		public _layerType:number;
		public _layer:GYSprite;
		protected _owner:AniRole;
		public _settingHeadH:number;
		public depthValue:number;
		/**角色透明度（默认1）*/public skinAlpha:number;		
		/**角色坐标是否变更(enterLoop-exitLoop之间)*/protected _posChanged:boolean;
		public static idCount:number = Date.now();
		protected _ownerData:OwnerData;
	}
}
/**
	{
		absX:世界坐标X,
		absY:世界坐标Y,
		areaRect:[角色占位区域的左边界,角色占位区域的上边界,角色占位区域宽度，角色占位区域的高度],
		roleType:角色类型，参考RoleType常量,
		roleID:角色ID，皮肤、技能挂钩动作
		id:唯一标识
	}  
 * **/